/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package flightlifter;

import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;

/**
 *
 * @author Matt
 */
public class Earth {

    FloatBuffer verticesFB;
    FloatBuffer uvFB;
    FloatBuffer normFB;
    float[] vertices;
    float[] uvs;
    float[] norms;
    short[] triangles;
    int latRes, lonRes; //number of
    float radius;
    PVector[][] heights;
    PVector[][] uvCoords;
    PVector[][] normals;
    int numVerts;

    public Earth(float radius, int latRes, int lonRes) {

        float texScale = latRes;

        this.latRes = latRes;
        this.lonRes = lonRes;
        this.radius = radius;




        heights = new PVector[latRes + 1][lonRes + 1];
        uvCoords = new PVector[latRes + 1][lonRes + 1];
        normals = new PVector[latRes + 1][lonRes + 1];

        //BUILD THE EARTH!
        float ang = 0;
        float el = 0;




        for (int j = 0; j <= lonRes; j++) {
            for (int i = 0; i <= latRes; i++) {

                heights[i][j] = new PVector();
                heights[i][j].x = radius * (float) Math.cos(ang) * (float) Math.sin(el);
                heights[i][j].y = radius * (float) Math.cos(el);
                heights[i][j].z = radius * (float) Math.sin(ang) * (float) Math.sin(el);


                uvCoords[i][j] = new PVector();
                uvCoords[i][j].y = (float) j / (lonRes)*texScale;
                uvCoords[i][j].x = -(float) i / (latRes)*texScale;

                normals[i][j] = new PVector(heights[i][j].x,
                        heights[i][j].y,
                        heights[i][j].z);


                normals[i][j].normalize();

                ang += Util.TWO_PI / (latRes);

            }
            el += Util.PI / (lonRes);
            ang = 0;
        }

        numVerts = (lonRes) * ((latRes) * 12 + 6);
        int numUVs = (lonRes) * ((latRes) * 8 + 4);

        vertices = new float[numVerts];
        norms = new float[numVerts];
        uvs = new float[numUVs];



        int index = 0;
        int uvindex = 0;

        for (int j = 0; j < lonRes; j++) {
            for (int i = 0; i < latRes; i++) {
                vertices[index] = heights[i][j + 1].x;
                vertices[index + 1] = heights[i][j + 1].y;
                vertices[index + 2] = heights[i][j + 1].z;

                norms[index] = normals[i][j + 1].x;
                norms[index + 1] = normals[i][j + 1].y;
                norms[index + 2] = normals[i][j + 1].z;

                uvs[uvindex] = uvCoords[i][j + 1].x;
                uvs[uvindex + 1] = uvCoords[i][j + 1].y;


                vertices[index + 3] = heights[i][j].x;
                vertices[index + 4] = heights[i][j].y;
                vertices[index + 5] = heights[i][j].z;

                norms[index + 3] = normals[i][j].x;
                norms[index + 4] = normals[i][j].y;
                norms[index + 5] = normals[i][j].z;

                uvs[uvindex + 2] = uvCoords[i][j].x;
                uvs[uvindex + 3] = uvCoords[i][j].y;


                vertices[index + 6] = heights[i + 1][j + 1].x;
                vertices[index + 7] = heights[i + 1][j + 1].y;
                vertices[index + 8] = heights[i + 1][j + 1].z;

                norms[index + 6] = normals[i + 1][j + 1].x;
                norms[index + 7] = normals[i + 1][j + 1].y;
                norms[index + 8] = normals[i + 1][j + 1].z;

                uvs[uvindex + 4] = uvCoords[i + 1][j + 1].x;
                uvs[uvindex + 5] = uvCoords[i + 1][j + 1].y;


                vertices[index + 9] = heights[i + 1][j].x;
                vertices[index + 10] = heights[i + 1][j].y;
                vertices[index + 11] = heights[i + 1][j].z;

                norms[index + 9] = normals[i + 1][j].x;
                norms[index + 10] = normals[i + 1][j].y;
                norms[index + 11] = normals[i + 1][j].z;

                uvs[uvindex + 6] = uvCoords[i + 1][j].x;
                uvs[uvindex + 7] = uvCoords[i + 1][j].y;

                index += 12;
                uvindex += 8;

            }

            vertices[index] = heights[0][j + 1].x;
            vertices[index + 1] = heights[0][j + 1].y;
            vertices[index + 2] = heights[0][j + 1].z;

            norms[index] = normals[0][j + 1].x;
            norms[index + 1] = normals[0][j + 1].y;
            norms[index + 2] = normals[0][j + 1].z;

            uvs[uvindex] = uvCoords[0][j + 1].x;
            uvs[uvindex + 1] = uvCoords[0][j + 1].y;


            vertices[index + 3] = heights[0][j].x;
            vertices[index + 4] = heights[0][j].y;
            vertices[index + 5] = heights[0][j].z;

            norms[index + 3] = normals[0][j].x;
            norms[index + 4] = normals[0][j].y;
            norms[index + 5] = normals[0][j].z;


            uvs[uvindex + 2] = uvCoords[0][j].x;
            uvs[uvindex + 3] = uvCoords[0][j].y;



            index += 6;
            uvindex += 4;
        }


        verticesFB = FlightLifter.allocFloats(vertices);
        uvFB = FlightLifter.allocFloats(uvs);
        normFB = FlightLifter.allocFloats(norms);
    }

    public void draw() {
        GL11.glColorMaterial(GL11.GL_FRONT, GL11.GL_AMBIENT);
        GL11.glColor4f(.1f, .1f, .1f, 1f);

        GL11.glColorMaterial(GL11.GL_FRONT, GL11.GL_DIFFUSE);
        GL11.glColor4f(.75f, .75f, .75f, 1f);

        //GL20.glUseProgram(0);
        //GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
        GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
        GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);

        GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);

        GL11.glVertexPointer(3, 0, verticesFB);
        GL11.glTexCoordPointer(2, 0, uvFB);
        GL11.glNormalPointer(12, normFB);

        GL11.glDrawArrays(GL11.GL_QUAD_STRIP, 0, numVerts / 3);

    }
}
